package atguigu.limit;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 计数器法是限流算法里最简单也是最容易实现的一种算法，一般我们会限制一秒钟能够通过的请求数。比如我们规定，对于A接口来说，
 * 我们1分钟的访问次数不能超过100个。那么我们可以这么做：在一开始的时候，我们可以设置一个计数器counter，每当一个请求过来的时候，
 * counter就加1，如果counter的值大于100并且该请求与第一个请求的间隔时间还在1分钟之内，那么说明请求数过多; 如果该请求与第一个请求的间隔时间大于1分钟，
 * 且counter的值还在限流范围内，那么就重置 counter。
 * <p>
 * <p>
 * 计算器算法存在的问题，可以怎么解决呢？
 */
public class CountAlgorithm {
    public static void main(String[] args) {
        CountAlgorithm countAlgorithm = new CountAlgorithm();
        countAlgorithm.limit();
    }

    private long timeStamp = System.currentTimeMillis(); // 当前时间
    AtomicInteger reqCount = new AtomicInteger(0); // 初始化计数器
    private final int limit = 100; // 时间窗口内最大请求数
    private final long interval = 1000 * 60; // 时间窗口ms


    public boolean limit() {
        long now = System.currentTimeMillis();
        if (now < timeStamp + interval) {
            // 在时间窗口内
            int andIncrement = reqCount.getAndIncrement();
            // 判断当前时间窗口内是否超过最大请求控制数
            return andIncrement <= limit;
        } else {
            timeStamp = now;
            // 超时后重置
            reqCount.set(0);
            return true;
        }
    }
}
